import { getPointTaskList, updatePointTask } from '@/api'
import { topId } from '@/components/PointSettingFormDialog'
import { ElMessage } from '@/stores/elMessage'
import type { PointData } from '@/types'
import { i18n } from '@/utils'
import { pointFilter } from '@/utils/pointFilter'
import { ConnectorLine, Marker, VectorLayer } from 'maptalks'
import { ref } from 'vue'
import { getLineCoordinates, handleCreatePath } from '.'
import { clearMenu, jumpToCoordinate, map } from './base'
import { clearDrawTool } from './drawTool'
import {
  clearDrawingHomePath,
  entryPoint,
  handleCreateHomePath,
  homePathDrawLayer,
  movePoint,
  setEntryPoint,
  setMovePoint
} from './home'
import { clearPathToolbarEvent } from './patrolPath'
import { configCarSpeed } from './pointConfig'
import { useRecordStore } from './record'
import { useRoadnet } from './roadnet'
import { deleteTaskEvent, handleTaskEvent, type TaskEvent } from './taskPoint'
import { missionTemplateId } from './template'

/**
 * 通用路线图层
 * @example 绘制路线
 * @example 录制路线
 * @example 路线模板
 */
export let pathLayer: VectorLayer

/**
 * 路线图层上所有点实例的集合
 * @example 绘制路线
 * @example 录制路线
 * @example 路线模板
 */
export const pathPoints = ref<Marker[]>([])

/**
 * 路线图层上所有点数据
 */
export const pathPointsData = ref<PointData[]>([])

/**
 * 记录插入模式的状态
 */
export const insertMode = ref<{
  active: boolean
  index: number
  position: 'before' | 'after'
  coordinates?: { x: number; y: number }
} | null>(null)

/**
 * 初始化路线图层
 */
export const initPathLayer = () => {
  pathLayer = new VectorLayer('line')
  pathLayer.addTo(map)
  initPathBtnLayer()
}

/**
 * 初始化中间按钮图层
 */
export let pathBtnLayer: VectorLayer
export const initPathBtnLayer = () => {
  pathBtnLayer = new VectorLayer('line-btn')
  pathBtnLayer.addTo(map)
}

/**
 * 清空路线图层
 */
export const clearPathLayer = () => {
  pathLayer.clear()
  pathBtnLayer.clear()
  pathPoints.value.length = 0
  pathPointsData.value.length = 0
  middleBtns.length = 0
}

/**
 * 路径点中间按钮集合
 */
export const middleBtns: Marker[] = []
/**
 * 添加路线点到路线图层中
 * @param pathPoint 路线点实例
 */
export const addPathPointToLayer = (pathPoint: Marker, index: number, coordinates: PointData[]) => {
  pathLayer.addGeometry(pathPoint)
  if (entryPoint) {
    pathPoint.setCoordinates(entryPoint.getCenter())
    setEntryPoint(null)
  }
  pathPoints.value.push(pathPoint)
  if (pathPoints.value.length >= 2) {
    const lastTwoPoints = pathPoints.value.slice(-2)
    const connectLine = new ConnectorLine(lastTwoPoints[0], lastTwoPoints[1], {
      showOn: 'always',
      symbol: {
        lineColor: '#ff930e'
      },
      zIndex: -1
    })
    pathLayer.addGeometry(connectLine)
    const lastPoint = lastTwoPoints[0]
    const nextPoint = lastTwoPoints[1]
    const middleBtn = {
      x: (lastPoint.getCoordinates().y + nextPoint.getCoordinates().y) / 2,
      y: (lastPoint.getCoordinates().x + nextPoint.getCoordinates().x) / 2
    }

    const btnPoint: Marker = createMiddleBtn(middleBtn, symbolConfig)

    //保存中间点
    middleBtns.push(btnPoint)
    pathBtnLayer.addGeometry(btnPoint)
    btnPoint.on('click', (e: { target: Marker }) => {
      const newMiddleBtn = {
        x: e.target.getCoordinates().y,
        y: e.target.getCoordinates().x,
        speed: 0,
        topId: null
      }
      coordinates.splice(index, 0, newMiddleBtn)
      /**
       * 清空图层和路径点、按钮总数
       */
      pathBtnLayer.clear()
      pathLayer.clear()
      pathPoints.value.length = 0
      middleBtns.length = 0
      initPath(coordinates)
    })
  }
}

export const activeNames = ref<string>('')
export const templatePathPoints = ref<Marker[] | undefined>()
/**
 * 绘制时每次点击触发的事件
 * @param e
 */

export const pathPointDrawendEvent = (e: { geometry: Marker }) => {
  const pathPoint = e.geometry

  pathPoint
    .setSymbol({
      textName: '',
      markerType: 'ellipse',
      markerFill: '#ff930e',
      markerWidth: 15,
      markerHeight: 15,
      textSize: 9
    })
    .on('click', (e: { target: Marker }) => {
      setEntryPoint(e.target)
    })
    .on('mouseenter', (e: { target: Marker }) => {
      setMovePoint(e.target)
    })
    .on('mouseout', () => {
      setMovePoint(null)
    })

  pathLayer.addGeometry(pathPoint)

  // 如果有预设坐标,使用预设坐标
  if (insertMode.value?.coordinates) {
    pathPoint.setCoordinates([insertMode.value.coordinates.x, insertMode.value.coordinates.y])
  } else if (entryPoint) {
    pathPoint.setCoordinates(entryPoint.getCenter())
    setEntryPoint(null)
  }

  if (insertMode.value) {
    const insertIndex =
      insertMode.value.position === 'before' ? insertMode.value.index : insertMode.value.index + 1

    pathPoints.value.splice(insertIndex, 0, pathPoint)

    // 清除原有连接线
    pathLayer.getGeometries().forEach((geo) => {
      if (geo instanceof ConnectorLine) {
        pathLayer.removeGeometry(geo)
      }
    })

    // 重新连接所有线段
    for (let i = 0; i < pathPoints.value.length - 1; i++) {
      const connectLine = new ConnectorLine(pathPoints.value[i], pathPoints.value[i + 1], {
        showOn: 'always',
        symbol: {
          lineColor: '#ff930e'
        },
        zIndex: -1
      })
      pathLayer.addGeometry(connectLine)
    }

    // 更新所有点的序号
    pathPoints.value.forEach((point, idx) => {
      point.setSymbol({
        ...point.getSymbol(),
        textName: idx + 1
      })
    })

    insertMode.value = null
  } else {
    pathPoints.value.push(pathPoint)
    activeNames.value = (pathPoints.value.length - 1).toString()
    pathPoint.setSymbol({
      ...pathPoint.getSymbol(),
      textName: pathPoints.value.length
    })

    if (pathPoints.value.length >= 2) {
      const lastTwoPoints = pathPoints.value.slice(-2)
      const connectLine = new ConnectorLine(lastTwoPoints[0], lastTwoPoints[1], {
        showOn: 'always',
        symbol: {
          lineColor: '#ff930e'
        },
        zIndex: -1
      })
      pathLayer.addGeometry(connectLine)
    }
  }
}

/**
 * 新建路线
 */
export const drawPathToolbarEvent = () => {
  const record = useRecordStore()
  if (record.endRecording()) {
    clearPath()
    clearDrawTool()
    clearPathToolbarEvent()
    topId.value = null
    missionTemplateId.value = undefined
    handleCreatePath('#ff931e', pathPointDrawendEvent)
    record.closeIsRecord()
    record.closeIsRecordPath()
    setDrawPathMenu()
  }
}

/**
 * 结束绘制路线时
 */
export const endDrawPath = () => {
  clearDrawTool()
  showPath(getLineCoordinates(pathPoints.value))
}

/**
 * 拖动前的值
 */
let dragendPoint: any

export const pathMenu = [
  {
    item: i18n.global.t('jie-shu'),
    click: endDrawPath
  }
]

const setDrawPathMenu = () => {
  clearMenu()
  map.setMenuItems(pathMenu)
}

/**
 * 新增任务点
 * @param pathPoint 路径点
 * @param index 路径点索引
 */
const addTaskPoint = (pathPoint: Marker, index: number) => {
  const pointCoordinates = {
    x: pathPoint.getCoordinates().y,
    y: pathPoint.getCoordinates().x
  }
  /**
   * 任务点坐标数据
   */
  const taskEvent: TaskEvent = {
    gps: JSON.stringify(pointCoordinates)
  }

  handleTaskEvent(taskEvent, () => {
    // 修改路线点颜色为任务点颜色
    pathPoint.setSymbol({
      textName: pathPointsData.value[index].speed === 0 ? '' : pathPointsData.value[index].speed,
      markerType: 'ellipse',
      markerFill: '#138C46',
      markerWidth: 15,
      markerHeight: 15,
      textSize: 9
    })
    // 更新路线数组的任务id
    pathPointsData.value[index].topId = topId.value
    clearDrawTool()
  })
}

/**
 * 获取任务点
 * @returns 任务点集合
 */
export const getTaskPoints = async () => {
  const res = await getPointTaskList()
  return res.data?.list || []
}

/**
 * 删除路径点
 * @param pathPoint 要删除的路径点
 * @param index 路径点索引
 */
export const deletePathPoint = async (pathPoint: Marker, index: number) => {
  topId.value = null

  pathPointsData.value.splice(index, 1)

  showPath(pathPointsData.value)

  const taskPointList = await getTaskPoints()
  //对比任务点是否在路线上
  for (const coordinate of taskPointList) {
    const newGps = JSON.parse(coordinate.gps)

    if (newGps.x === pathPoint.getCoordinates().y && newGps.y === pathPoint.getCoordinates().x) {
      /**
       * 删除任务点
       */
      deleteTaskEvent(coordinate.id)
      break
    }
  }
}

/**
 * 配置路径点的任务
 * @param pathPoint 路径点
 * @param index 路径点索引
 */
export const configureTaskPoint = async (pathPoint: Marker, index: number) => {
  const taskPointList = await getTaskPoints()
  let found = false
  //对比任务点是否在路线上
  for (const coordinate of taskPointList) {
    const newGps = JSON.parse(coordinate.gps)

    if (newGps.x === pathPoint.getCoordinates().y && newGps.y === pathPoint.getCoordinates().x) {
      /**
       * 修改任务点
       */
      handleTaskEvent(coordinate, () => {
        pathPointsData.value[index].topId = coordinate.id
      })
      found = true
      break
    }
  }
  if (!found) {
    /**
     * 新增任务点
     */
    addTaskPoint(pathPoint, index)
  }
}

export const getPointMenuItems = (pathPoint: Marker, index: number) => {
  return [
    // {
    //   item: i18n.global.t('pei-zhi-ren-wu'),
    //   // 配置任务
    //   click: () => configureTaskPoint(pathPoint, index)
    // },
    {
      item: i18n.global.t('tian-jia-fan-hang-dian'),
      click: () => {
        handleCreateHomePath(pathPoint)
      }
    },
    {
      item: i18n.global.t('bian-ji-che-su'),
      click: () => {
        configCarSpeed(pathPoint, index)
      }
    },
    {
      item: i18n.global.t('shan-chu-ren-wu'),
      click: async () => {
        topId.value = null
        const taskPointList = await getTaskPoints()
        let found = false
        //对比任务点是否在路线上
        for (const coordinate of taskPointList) {
          const newGps = JSON.parse(coordinate.gps)

          if (
            newGps.x === pathPoint.getCoordinates().y &&
            newGps.y === pathPoint.getCoordinates().x
          ) {
            /**
             * 删除任务点
             */
            deleteTaskEvent(coordinate.id)
            pathPoint.setSymbol({
              textName:
                pathPointsData.value[index].speed === 0 ? '' : pathPointsData.value[index].speed,
              markerType: 'ellipse',
              markerFill: index === 0 ? '#FF0070' : '#8D70DD',
              markerWidth: 15,
              markerHeight: 15,
              textSize: 9
            })
            pathPointsData.value[index].topId = null
            found = true
            break
          }
        }
        if (!found) {
          ElMessage({
            type: 'warning',
            message: i18n.global.t('ci-lu-jing-dian-wu-ren-wu')
          })
        }
      }
    },
    {
      item: i18n.global.t('shan-chu-lu-jing-dian'),
      // 删除路径点
      click: () => deletePathPoint(pathPoint, index)
    }
  ]
}
export const setPointMenu = () => {
  pathPoints.value.forEach((pathPoint, index) => {
    const pointMenuItems = getPointMenuItems(pathPoint, index)
    pathPoint.setMenuItems(pointMenuItems)
  })
}

export const clearPath = () => {
  clearPathLayer()
  clearMenu()
}

export const simplifyPath = () => {
  pathPoints.value.forEach((pathPoint) => {
    pathPoint.removeMenu()
  })
  const newCoordinates: any = pointFilter(pathCoordinates.value)

  clearPath()
  initPath(newCoordinates)
  initPathData(newCoordinates)
  jumpToCoordinate(newCoordinates[0].y, newCoordinates[0].x, map)
  clearMenu()
  map.setMenuItems([
    {
      item: i18n.global.t('qing-kong'),
      click: clearPath
    }
  ])
}

export const clearPathMenu = [
  {
    item: i18n.global.t('qing-kong'),
    click: clearPath
  },
  {
    item: i18n.global.t('jian-hua-lu-xian'),
    click: simplifyPath
  }
]
export const setDrawEndMenu = () => {
  map.setMenuItems(clearPathMenu)
}

export const clearToolbarEvent = () => {
  const roadnet = useRoadnet()
  const record = useRecordStore()
  clearPathLayer()
  roadnet.clearRoadnetPathLayer()
  roadnet.clearRoadnetLayer()
  clearDrawTool()
  record.closeIsRecord()
  if (homePathDrawLayer) {
    clearDrawingHomePath()
  }
  clearMenu()
}

/**
 * 绘制路线上点的颜色
 * @param index 路线点索引
 * @param coordinates 路线点数据集合
 * @param taskPointList 任务点集合
 * @returns
 */
export const getMarkerFill = (index: number, coordinate: PointData) => {
  if (coordinate.topId) {
    return '#138C46'
  } else if (!coordinate.topId && index === 0) {
    return '#FF0070'
  } else {
    return '#8D70DD'
  }
}

export const getPoints = (coordinates: PointData[]) => {
  const pointMarkers: Marker[] = []
  setPointEvent(coordinates, pointMarkers)
  return pointMarkers
}

const setPointEvent = (coordinates: PointData[], pointMarkers: Marker[]) => {
  for (const [index, coordinate] of coordinates.entries()) {
    const pointMarker = new Marker([coordinate.y, coordinate.x], {
      symbol: {
        textName: coordinate.speed,
        markerType: 'ellipse',
        markerFill: getMarkerFill(index, coordinate),
        markerWidth: 15,
        markerHeight: 15,
        textSize: 9
      },
      draggable: true
    })
    pointMarker
      .on('mousedown', (e: { target: Marker }) => {
        // 拖动前的值
        dragendPoint = {
          x: e.target.getCoordinates().y,
          y: e.target.getCoordinates().x
        }
      })
      //拖拽后
      .on('dragend', async function (e: { target: Marker }) {
        if (movePoint) {
          pointMarker.setCoordinates(movePoint.getCenter())
          setMovePoint(null)
        }
        const newCoordinate = [e.target.getCoordinates().x, e.target.getCoordinates().y]
        coordinates[index] = {
          x: newCoordinate[1],
          y: newCoordinate[0],
          speed: coordinates[index].speed,
          topId: coordinates[index].topId
        }
        for (let index = 0; index < coordinates.length; index++) {
          let middleBtn: { x: number; y: number } | undefined
          if (index === 0) {
            middleBtn = {
              x: (coordinates[index].x + coordinates[index + 1].x) / 2,
              y: (coordinates[index].y + coordinates[index + 1].y) / 2
            }
            middleBtns[index] = createMiddleBtn(middleBtn, symbolConfig)
          } else if (index === coordinates.length - 1) {
            middleBtn = {
              x: (coordinates[index - 1].x + coordinates[index].x) / 2,
              y: (coordinates[index - 1].y + coordinates[index].y) / 2
            }
            middleBtns[index - 1] = createMiddleBtn(middleBtn, symbolConfig)
          } else {
            const middleBtn1 = {
              x: (coordinates[index - 1].x + coordinates[index].x) / 2,
              y: (coordinates[index - 1].y + coordinates[index].y) / 2
            }
            const middleBtn2 = {
              x: (coordinates[index].x + coordinates[index + 1].x) / 2,
              y: (coordinates[index].y + coordinates[index + 1].y) / 2
            }
            middleBtns[index - 1] = createMiddleBtn(middleBtn1, symbolConfig)
            middleBtns[index] = createMiddleBtn(middleBtn2, symbolConfig)
          }
        }
        pathBtnLayer.clear()
        middleBtns.forEach((btn: Marker, index) => {
          pathBtnLayer.addGeometry(btn)
          btn.on('click', (e: { target: Marker }) => {
            const newMiddleBtn = {
              x: e.target.getCoordinates().y,
              y: e.target.getCoordinates().x,
              speed: 0,
              topId: null
            }
            coordinates.splice(index + 1, 0, newMiddleBtn)
            pathBtnLayer.clear()
            pathLayer.clear()
            pathPoints.value.length = 0

            middleBtns.length = 0
            initPath(coordinates)
          })
        })
        //任务点
        const newTaskPoint = JSON.stringify({
          x: e.target.getCoordinates().y,
          y: e.target.getCoordinates().x
        })
        const taskPointList = await getTaskPoints()
        taskPointList.map(async (coordinate: any) => {
          const newGps = JSON.parse(coordinate.gps)

          if (newGps.x === dragendPoint.x && newGps.y === dragendPoint.y) {
            await updatePointTask({ id: coordinate.id, gps: newTaskPoint })
          }
        })
      })
      .on('mouseenter', (e: { target: Marker }) => {
        setMovePoint(e.target)
      })
      .on('mouseout', () => {
        setMovePoint(null)
      })

    pointMarkers.push(pointMarker)
  }
}

/**
 *
 * @param coords 坐标
 * @param symbolConfig 样式
 * @returns 中间按钮Marker
 */
function createMiddleBtn(
  coords: { x: number; y: number },
  symbolConfig: {
    textName: string
    textFill: string
    textSize: number
  }
) {
  const btnPoint = new Marker([coords.y, coords.x], {
    symbol: symbolConfig
  })
  return btnPoint
}

const symbolConfig = {
  textName: '+',
  textFill: 'rgba(255, 255, 255, 0.5)',
  textSize: 24
}

export const initPath = async (coordinates: PointData[]) => {
  templatePathPoints.value = getPoints(coordinates)
  if (templatePathPoints.value) {
    templatePathPoints.value.forEach((pathPoint: Marker, index: number) => {
      addPathPointToLayer(pathPoint, index, coordinates)
    })
  }
  setPointMenu()
}

export const initPathData = (coordinates: PointData[]) => {
  pathPointsData.value = coordinates
}

const pathCoordinates = ref<PointData[]>([])
export const showPath = (coordinates: PointData[]) => {
  pathLayer.clear()
  pathBtnLayer.clear()
  pathPoints.value.length = 0
  middleBtns.length = 0
  clearMenu()
  pathCoordinates.value = coordinates
  initPath(coordinates)
  initPathData(coordinates)
  jumpToCoordinate(coordinates[0].y, coordinates[0].x, map)
  clearMenu()
  setDrawEndMenu()
}

/**
 * 添加激活插入模式的方法
 */
export const activateInsertMode = (
  index: number,
  position: 'before' | 'after',
  coordinates?: { x: number; y: number }
) => {
  insertMode.value = {
    active: true,
    index,
    position,
    coordinates
  }

  // 创建新的 Marker 并触发 pathPointDrawendEvent
  const newPoint = new Marker([0, 0], {
    symbol: {
      markerType: 'ellipse',
      markerFill: '#ff930e',
      markerWidth: 15,
      markerHeight: 15
    }
  })

  pathPointDrawendEvent({ geometry: newPoint })
  endDrawPath()
}
